from flask import Flask, render_template, request, redirect, url_for, flash, jsonify, Blueprint
import db_manager as dbm
from datetime import datetime
import pytz
import os
import json
from werkzeug.utils import secure_filename

app = Flask(__name__)
app.config['SECRET_KEY'] = 'your-secret-key'

# 配置上传文件存储路径
app.config['EMPLOYEE_FILES_DIR'] = os.path.join('static', 'employees')
app.config['RESIGNED_EMPLOYEES_DIR'] = os.path.join('static', 'resigned_employees')
app.config['ALLOWED_EXTENSIONS'] = {'png', 'jpg', 'jpeg', 'gif', 'pdf'}
app.config['MAX_CONTENT_LENGTH'] = 16 * 1024 * 1024  # 限制上传文件大小为16MB

# 创建Blueprint
employee_bp = Blueprint('employee', __name__, url_prefix='/employee')

# 确保上传目录存在
# @app.before_first_request  # 这个装饰器在新版Flask中已被移除
def setup_folders():
    """确保所有必要的目录都存在"""
    directories = [
        app.config['EMPLOYEE_FILES_DIR'],
        app.config['RESIGNED_EMPLOYEES_DIR']
    ]
    for directory in directories:
        if not os.path.exists(directory):
            os.makedirs(directory, exist_ok=True)

# 使用with app.app_context()来替代before_first_request
with app.app_context():
    setup_folders()  # 直接调用函数
    dbm.init_db()    # 初始化数据库

# 检查文件扩展名是否允许
def allowed_file(filename):
    return '.' in filename and \
           filename.rsplit('.', 1)[1].lower() in app.config['ALLOWED_EXTENSIONS']

# 路由：首页
@employee_bp.route('/')
def index():
    employees = dbm.get_all_employees()
    return render_template('index.html', employees=employees)

# 路由：添加员工
@employee_bp.route('/add', methods=['GET', 'POST'])
def add_employee():
    try:
        if request.method == 'POST':
            name = request.form['name']
            id_card = request.form['id_card']
            phone = request.form['phone']
            department = request.form['department']
            position = request.form['position']
            
            success, message = dbm.add_employee(
                name=name,
                id_card=id_card,
                phone=phone,
                department=department,
                position=position
            )
            
            if success:
                try:
                    # 获取新添加的员工信息
                    employees = dbm.search_employees(id_card)
                    if employees and len(employees) > 0:
                        employee = employees[0]  # 获取第一个匹配的员工
                        employee_id = employee['id']
                        
                        # 获取员工文件夹路径
                        employee_folder = dbm.get_employee_folder(employee)
                        
                        # 确保文件夹存在
                        if not os.path.exists(employee_folder):
                            os.makedirs(employee_folder)
                        
                        # 处理证件文件
                        certificate_data = {}
                        
                        # 处理主要证件（身份证正反面、学历证书、学位证书）
                        for field in ['id_card_front', 'id_card_back', 'diploma', 'degree']:
                            if field in request.files and request.files[field].filename:
                                file = request.files[field]
                                if file and allowed_file(file.filename):
                                    # 如果存在旧文件，先删除
                                    if field in employee and employee[field]:
                                        old_file_path = os.path.join(app.static_folder, employee[field])
                                        if os.path.exists(old_file_path):
                                            os.remove(old_file_path)
                                            print(f"删除旧文件: {old_file_path}")  # 调试信息
                                    
                                    # 获取文件扩展名
                                    _, ext = os.path.splitext(file.filename)
                                    
                                    # 简化的文件名映射
                                    filename_map = {
                                        'id_card_front': f'身份证正面{ext}',
                                        'id_card_back': f'身份证反面{ext}',
                                        'diploma': f'学历证书{ext}',
                                        'degree': f'学位证书{ext}'
                                    }
                                    
                                    filename = filename_map.get(field)
                                    
                                    file_path = os.path.join(employee_folder, filename)
                                    file.save(file_path)
                                    print(f"保存新文件: {file_path}")  # 调试信息
                                    
                                    # 存储相对路径
                                    relative_path = os.path.join('employees', os.path.basename(employee_folder), filename)
                                    relative_path = relative_path.replace('\\', '/')
                                    certificate_data[field] = relative_path
                        
                        # 处理其他证书
                        other_certs = []
                        cert_names = request.form.getlist('cert_name')
                        cert_files = request.files.getlist('cert_file')
                        
                        for i, (name, file) in enumerate(zip(cert_names, cert_files)):
                            if name:  # 如果证书名称不为空
                                cert_data = {'name': name}
                                
                                # 如果上传了新文件
                                if file and file.filename and allowed_file(file.filename):
                                    # 获取文件扩展名
                                    _, ext = os.path.splitext(file.filename)
                                    
                                    # 直接使用证书名称作为文件名
                                    filename = f"{name}{ext}"
                                    
                                    file_path = os.path.join(employee_folder, filename)
                                    file.save(file_path)
                                    print(f"保存文件: {file_path}")  # 调试信息
                                    
                                    # 存储相对路径
                                    relative_path = os.path.join('employees', os.path.basename(employee_folder), filename)
                                    relative_path = relative_path.replace('\\', '/')
                                    cert_data['image'] = relative_path
                                # 如果没有上传新文件，但有对应的旧证书，保留旧证书的图片
                                elif employee.get('other_certificates') and i < len(employee['other_certificates']):
                                    old_cert = employee['other_certificates'][i]
                                    if 'image' in old_cert:
                                        cert_data['image'] = old_cert['image']
                                        print(f"保留旧证书图片: {old_cert['image']}")  # 调试信息
                                
                                other_certs.append(cert_data)
                        
                        if other_certs:
                            certificate_data['other_certificates'] = other_certs
                        
                        # 更新证件信息
                        if certificate_data:
                            dbm.update_employee_certificates(employee_id, certificate_data)
                        
                        # 创建个人信息文件
                        update_employee_info_file(employee, employee_folder)
                
                except Exception as e:
                    print(f"处理证件文件时出错：{str(e)}")
                
                flash(f'员工 {employee["name"]} 添加成功！', 'success')
                return redirect(url_for('employee.index'))
            else:
                flash(f'员工添加失败！原因：{message}', 'error')
                return render_template('add.html')
        else:
            print("GET请求：渲染添加员工页面")  # 调试信息
            return render_template('add.html')
    except Exception as e:
        print(f"添加员工时出错：{str(e)}")  # 调试信息
        flash(f'系统错误：{str(e)}', 'error')
        return render_template('add.html')

# 路由：编辑员工
@employee_bp.route('/edit/<int:id>', methods=['GET', 'POST'])
def edit_employee(id):
    employee = dbm.get_employee_by_id(id)
    
    if not employee:
        flash('员工不存在！', 'error')
        return redirect(url_for('employee.index'))
    
    # 记录更新前的员工文件夹
    old_folder = dbm.get_employee_folder(employee)
    print(f"旧文件夹路径: {old_folder}")  # 调试信息
    
    if request.method == 'POST':
        name = request.form['name']
        data = {
            'name': name,
            'department': request.form['department'],
            'position': request.form['position'],
            'id_card': request.form['id_card'],
            'phone': request.form['phone']
        }
        
        success, message = dbm.update_employee(id, data)
        
        if success:
            try:
                # 获取更新后的员工信息
                updated_employee = dbm.get_employee_by_id(id)
                # 获取新的文件夹路径
                new_folder = dbm.get_employee_folder(updated_employee)
                print(f"新文件夹路径: {new_folder}")  # 调试信息
                
                # 如果文件夹发生变化，移动文件并更新数据库中的路径
                if old_folder != new_folder:
                    # 确保新文件夹存在
                    if not os.path.exists(new_folder):
                        os.makedirs(new_folder)
                    
                    # 如果旧文件夹存在，移动文件
                    if os.path.exists(old_folder):
                        try:
                            # 移动所有文件到新文件夹
                            for filename in os.listdir(old_folder):
                                old_file = os.path.join(old_folder, filename)
                                new_file = os.path.join(new_folder, filename)
                                if os.path.isfile(old_file):
                                    print(f"移动文件: {old_file} -> {new_file}")  # 调试信息
                                    os.rename(old_file, new_file)
                            
                            # 删除旧文件夹（如果为空）
                            if os.path.exists(old_folder) and not os.listdir(old_folder):
                                os.rmdir(old_folder)
                                print(f"删除空文件夹: {old_folder}")  # 调试信息
                        except Exception as e:
                            print(f"移动文件时出错：{str(e)}")
                    
                    # 更新所有文件路径
                    certificate_data = {}
                    
                    # 更新主要证件路径
                    for field in ['id_card_front', 'id_card_back', 'diploma', 'degree']:
                        if field in updated_employee and updated_employee[field]:
                            old_path = updated_employee[field]
                            # 从旧路径中提取文件名
                            old_filename = os.path.basename(old_path)
                            # 构建新路径
                            new_path = os.path.join('employees', os.path.basename(new_folder), old_filename)
                            new_path = new_path.replace('\\', '/')
                            certificate_data[field] = new_path
                            print(f"更新{field}路径: {old_path} -> {new_path}")  # 调试信息
                    
                    # 更新其他证书路径
                    if 'other_certificates' in updated_employee and updated_employee['other_certificates']:
                        other_certs = []
                        for cert in updated_employee['other_certificates']:
                            if 'image' in cert and cert['image']:
                                old_path = cert['image']
                                # 从旧路径中提取文件名
                                old_filename = os.path.basename(old_path)
                                # 构建新路径
                                new_path = os.path.join('employees', os.path.basename(new_folder), old_filename)
                                new_path = new_path.replace('\\', '/')
                                cert['image'] = new_path
                                print(f"更新其他证书路径: {old_path} -> {new_path}")  # 调试信息
                            other_certs.append(cert)
                        certificate_data['other_certificates'] = other_certs
                    
                    # 更新数据库中的文件路径
                    if certificate_data:
                        success, update_message = dbm.update_employee_certificates(id, certificate_data)
                        if not success:
                            print(f"更新文件路径失败: {update_message}")  # 调试信息
                
                # 更新个人信息文件
                update_employee_info_file(updated_employee, new_folder)
            
            except Exception as e:
                print(f"处理文件夹时出错：{str(e)}")
            
            flash(f'员工 {name} 更新成功！', 'success')
            return redirect(url_for('employee.index'))
        else:
            flash(f'员工 {name} 更新失败！', 'error')
    
    return render_template('edit.html', employee=employee)

# 路由：删除员工
@employee_bp.route('/delete/<int:id>')
def delete_employee(id):
    employee = dbm.get_employee_by_id(id)
    
    if not employee:
        flash('员工不存在！', 'error')
        return redirect(url_for('employee.index'))
    
    name = employee['name']
    success, message = dbm.delete_employee(id)
    
    if success:
        flash(f'员工 {name} {message}', 'success')  # 使用从 delete_employee 返回的消息
    else:
        flash(f'员工 {name} 删除失败！原因：{message}', 'error')
    
    return redirect(url_for('employee.index'))

# 路由：显示数据库内容
@employee_bp.route('/api/employees')
def show_database():
    employees = dbm.get_all_employees()
    result = []
    for employee in employees:
        # 处理日期格式
        hire_date = employee.get('hire_date', '')
        if hire_date:
            try:
                # 尝试解析日期字符串
                if isinstance(hire_date, str):
                    hire_date = datetime.strptime(hire_date, '%Y-%m-%d')
                hire_date = hire_date.strftime('%Y-%m-%d')
            except:
                hire_date = str(hire_date)
        
        result.append({
            'id': employee.get('id'),
            'name': employee.get('name'),
            'id_card': employee.get('id_card'),
            'phone': employee.get('phone'),
            'department': employee.get('department'),
            'position': employee.get('position'),
            'hire_date': hire_date
        })
    return {'employees': result}

# 路由：搜索员工
@employee_bp.route('/search', methods=['GET'])
def search_employees():
    search_term = request.args.get('term', '')
    if search_term:
        employees = dbm.search_employees(search_term)
    else:
        employees = dbm.get_all_employees()
    
    return render_template('index.html', employees=employees, search_term=search_term)

# 路由：员工详情
@employee_bp.route('/detail/<int:id>')
def employee_detail(id):
    employee = dbm.get_employee_by_id(id)
    
    if not employee:
        flash('员工不存在！', 'error')
        return redirect(url_for('employee.index'))
    
    # 格式化日期
    if 'hire_date' in employee and employee['hire_date']:
        if isinstance(employee['hire_date'], str):
            try:
                employee['hire_date'] = datetime.strptime(employee['hire_date'], '%Y-%m-%d')
            except ValueError:
                employee['hire_date'] = employee['hire_date']
    
    # 检查所有证件文件是否存在
    file_status = {}
    for field in ['id_card_front', 'id_card_back', 'diploma', 'degree']:
        if field in employee and employee[field]:
            file_status[field] = check_file_exists(employee[field])
    
    # 检查其他证书文件
    if 'other_certificates' in employee and employee['other_certificates']:
        file_status['other_certificates'] = []
        for cert in employee['other_certificates']:
            if 'image' in cert and cert['image']:
                status = check_file_exists(cert['image'])
                file_status['other_certificates'].append(status)
    
    return render_template('detail.html', employee=employee)

# 路由：离职员工列表
@employee_bp.route('/resigned')
def resigned_employees():
    employees = dbm.get_all_resigned_employees()
    # 格式化日期
    for employee in employees:
        if 'hire_date' in employee and employee['hire_date']:
            if isinstance(employee['hire_date'], str):
                try:
                    employee['hire_date'] = datetime.strptime(employee['hire_date'], '%Y-%m-%d')
                except ValueError:
                    employee['hire_date'] = employee['hire_date']
        if 'resign_date' in employee and employee['resign_date']:
            if isinstance(employee['resign_date'], str):
                try:
                    employee['resign_date'] = datetime.strptime(employee['resign_date'], '%Y-%m-%d')
                except ValueError:
                    employee['resign_date'] = employee['resign_date']
    return render_template('resigned.html', employees=employees)

# 路由：离职员工详情
@employee_bp.route('/resigned/detail/<int:id>')
def resigned_detail(id):
    employee = dbm.get_resigned_employee_by_id(id)
    
    if not employee:
        flash('离职员工不存在！', 'error')
        return redirect(url_for('employee.resigned_employees'))
    
    # 格式化日期
    if 'hire_date' in employee and employee['hire_date']:
        if isinstance(employee['hire_date'], str):
            try:
                employee['hire_date'] = datetime.strptime(employee['hire_date'], '%Y-%m-%d')
            except ValueError:
                employee['hire_date'] = employee['hire_date']
    if 'resign_date' in employee and employee['resign_date']:
        if isinstance(employee['resign_date'], str):
            try:
                employee['resign_date'] = datetime.strptime(employee['resign_date'], '%Y-%m-%d')
            except ValueError:
                employee['resign_date'] = employee['resign_date']
    
    # 检查所有证件文件是否存在
    file_status = {}
    for field in ['id_card_front', 'id_card_back', 'diploma', 'degree']:
        if field in employee and employee[field]:
            file_status[field] = check_file_exists(employee[field])
    
    # 检查其他证书文件
    if 'other_certificates' in employee and employee['other_certificates']:
        file_status['other_certificates'] = []
        for cert in employee['other_certificates']:
            if 'image' in cert and cert['image']:
                status = check_file_exists(cert['image'])
                file_status['other_certificates'].append(status)
    
    return render_template('resigned_detail.html', employee=employee)

# 路由：编辑证件
@employee_bp.route('/edit_certificates/<int:id>', methods=['GET', 'POST'])
def edit_certificates(id):
    employee = dbm.get_employee_by_id(id)
    
    if not employee:
        flash('员工不存在！', 'error')
        return redirect(url_for('employee.index'))
    
    if request.method == 'POST':
        try:
            # 获取员工文件夹路径
            employee_folder = dbm.get_employee_folder(employee)
            
            # 确保文件夹存在
            if not os.path.exists(employee_folder):
                os.makedirs(employee_folder)
            
            # 处理证件文件
            certificate_data = {}
            
            # 处理主要证件（身份证正反面、学历证书、学位证书）
            for field in ['id_card_front', 'id_card_back', 'diploma', 'degree']:
                if field in request.files and request.files[field].filename:
                    file = request.files[field]
                    if file and allowed_file(file.filename):
                        # 如果存在旧文件，先删除
                        if field in employee and employee[field]:
                            old_file_path = os.path.join(app.static_folder, employee[field])
                            if os.path.exists(old_file_path):
                                os.remove(old_file_path)
                        
                        # 获取文件扩展名
                        _, ext = os.path.splitext(file.filename)
                        
                        # 简化的文件名映射
                        filename_map = {
                            'id_card_front': f'身份证正面{ext}',
                            'id_card_back': f'身份证反面{ext}',
                            'diploma': f'学历证书{ext}',
                            'degree': f'学位证书{ext}'
                        }
                        
                        filename = filename_map.get(field)
                        file_path = os.path.join(employee_folder, filename)
                        file.save(file_path)
                        
                        # 存储相对路径
                        relative_path = os.path.join('employees', os.path.basename(employee_folder), filename)
                        relative_path = relative_path.replace('\\', '/')
                        certificate_data[field] = relative_path
            
            # 处理其他证书
            other_certs = []
            cert_names = request.form.getlist('cert_name')
            cert_files = request.files.getlist('cert_file')
            
            for i, (name, file) in enumerate(zip(cert_names, cert_files)):
                if name:  # 如果证书名称不为空
                    cert_data = {'name': name}
                    
                    # 如果上传了新文件
                    if file and file.filename and allowed_file(file.filename):
                        # 获取文件扩展名
                        _, ext = os.path.splitext(file.filename)
                        
                        # 直接使用证书名称作为文件名
                        filename = f"{name}{ext}"
                        
                        file_path = os.path.join(employee_folder, filename)
                        file.save(file_path)
                        print(f"保存文件: {file_path}")  # 调试信息
                        
                        # 存储相对路径
                        relative_path = os.path.join('employees', os.path.basename(employee_folder), filename)
                        relative_path = relative_path.replace('\\', '/')
                        cert_data['image'] = relative_path
                    # 如果没有上传新文件，但有对应的旧证书，保留旧证书的图片
                    elif employee.get('other_certificates') and i < len(employee['other_certificates']):
                        old_cert = employee['other_certificates'][i]
                        if 'image' in old_cert:
                            cert_data['image'] = old_cert['image']
                            print(f"保留旧证书图片: {old_cert['image']}")  # 调试信息
                    
                    other_certs.append(cert_data)
            
            if other_certs:
                certificate_data['other_certificates'] = other_certs
            
            # 更新证件信息
            if certificate_data:
                dbm.update_employee_certificates(id, certificate_data)
            
            flash('证件信息更新成功！', 'success')
            return redirect(url_for('employee.employee_detail', id=id))
            
        except Exception as e:
            print(f"更新证件信息时出错：{str(e)}")
            flash(f'更新证件信息失败！错误：{str(e)}', 'error')
    
    return render_template('edit_certificates.html', employee=employee)

# 添加一个新的函数用于更新个人信息文件
def update_employee_info_file(employee, folder_path):
    """更新员工个人信息文件"""
    try:
        info_file_path = os.path.join(folder_path, 'personal_info.txt')
        hire_date = employee.get('hire_date', '')
        if isinstance(hire_date, str):
            hire_date = datetime.strptime(hire_date, '%Y-%m-%d')
        
        with open(info_file_path, 'w', encoding='utf-8') as f:
            f.write(f"员工个人信息\n")
            f.write(f"='='='='='='='='='='='='='=\n")
            f.write(f"姓名：{employee.get('name', '')}\n")
            f.write(f"身份证号：{employee.get('id_card', '')}\n")
            f.write(f"手机号：{employee.get('phone', '')}\n")
            f.write(f"部门：{employee.get('department', '')}\n")
            f.write(f"职位：{employee.get('position', '')}\n")
            f.write(f"入职时间：{hire_date.strftime('%Y-%m-%d') if hire_date else ''}\n")
            f.write(f"='='='='='='='='='='='='='=\n")
            f.write(f"最后更新时间：{datetime.now().strftime('%Y-%m-%d')}")
        return True
    except Exception as e:
        print(f"更新个人信息文件时出错：{str(e)}")
        return False

# 添加一个用于检查文件是否存在的辅助函数
def check_file_exists(filepath):
    """检查文件是否存在，并返回完整的文件信息"""
    try:
        full_path = os.path.join(app.static_folder, filepath)
        exists = os.path.isfile(full_path)
        print(f"检查文件: {filepath}")  # 调试信息
        print(f"完整路径: {full_path}")  # 调试信息
        print(f"文件是否存在: {exists}")  # 调试信息
        if exists:
            print(f"文件大小: {os.path.getsize(full_path)}")  # 调试信息
        return {
            'filepath': filepath,
            'full_path': full_path,
            'exists': exists,
            'size': os.path.getsize(full_path) if exists else 0
        }
    except Exception as e:
        print(f"检查文件时出错: {str(e)}")  # 调试信息
        return {
            'filepath': filepath,
            'full_path': None,
            'exists': False,
            'size': 0,
            'error': str(e)
        }

# 路由：删除证件文件
@employee_bp.route('/delete_file/<int:id>/<field>', methods=['POST'])
def delete_file(id, field):
    try:
        employee = dbm.get_employee_by_id(id)
        if not employee:
            return jsonify({'success': False, 'message': '员工不存在'})
        
        # 获取文件路径
        file_path = None
        certificate_data = {}
        
        if field.startswith('other_cert_'):
            # 处理其他证书
            index = int(field.split('_')[-1])
            if 'other_certificates' in employee and index < len(employee['other_certificates']):
                cert = employee['other_certificates'][index]
                if 'image' in cert:
                    # 修改文件路径的获取方式
                    file_path = os.path.join(app.static_folder, cert['image'])
                    print(f"准备删除文件: {file_path}")  # 调试信息
                    
                    # 保留其他证书，只移除要删除的证书
                    other_certs = []
                    for i, c in enumerate(employee['other_certificates']):
                        if i != index:
                            other_certs.append(c)
                    certificate_data['other_certificates'] = other_certs
        else:
            # 处理主要证件
            if field in employee and employee[field]:
                file_path = os.path.join(app.static_folder, employee[field])
                certificate_data[field] = None
        
        if file_path and os.path.exists(file_path):
            # 删除文件
            os.remove(file_path)
            print(f"文件已删除: {file_path}")  # 调试信息
            
            # 更新数据库
            success, message = dbm.update_employee_certificates(id, certificate_data)
            if not success:
                print(f"更新数据库失败: {message}")  # 调试信息
                return jsonify({'success': False, 'message': message})
            
            return jsonify({'success': True})
        else:
            print(f"文件不存在: {file_path}")  # 调试信息
            return jsonify({'success': False, 'message': '文件不存在'})
            
    except Exception as e:
        print(f"删除文件时出错：{str(e)}")
        return jsonify({'success': False, 'message': str(e)})

# 路由：删除离职员工
@employee_bp.route('/delete_resigned/<int:id>')
def delete_resigned_employee(id):
    # 获取离职员工信息
    employee = dbm.get_resigned_employee_by_id(id)
    
    if not employee:
        flash('离职员工不存在！', 'error')
        return redirect(url_for('employee.resigned_employees'))
    
    name = employee['name']
    success, message = dbm.delete_resigned_employee(id)
    
    if success:
        flash(f'离职员工 {name} {message}', 'success')
    else:
        flash(f'离职员工 {name} 删除失败！原因：{message}', 'error')
    
    return redirect(url_for('employee.resigned_employees'))

# 注册Blueprint
app.register_blueprint(employee_bp)

# 在主应用中添加根路由重定向
@app.route('/')
def index():
    return redirect(url_for('employee.index'))

if __name__ == '__main__':
    app.run(debug=True, port=9002)